/**
 * 微信网页登陆
 * https://www.yuque.com/docs/share/586f7fce-7cf8-4644-9fc7-acf9e25a87a1
 */
class WxOfficialServerPlugin {
    constructor({
                    //公众平台申请的公众号appid
                    appid="wxb82ed6f75c3a22ad",
                    //公众平台申请的公众号appsecret
                    appsecret="999915ad9371781036b2bf8f917a28fd",
                    //微信服务的code通过此地址给后端
                    redirect_uri="http://minglie8888.vaiwan.com/wx/getCode",
                    //本地开发不方便redirect_uri会转发到proxy_redirect_uri
                    proxy_redirect_uri="http://minglie8888.vaiwan.com/wx/wxcallback/local",
                    //前端的wx.config参数,通过此地址获取
                    wxConfigServerUrl="/proxyScan",
                    //登陆成功后默认跳转的地址,后端会带上openid
                    defaultSuccessRedirectUrl="",
                }) {
        this.appid=appid;
        this.appsecret=appsecret;
        this.redirect_uri=redirect_uri;
        this.proxy_redirect_uri=proxy_redirect_uri;
        this.wxConfigServerUrl=wxConfigServerUrl;
        this.defaultSuccessRedirectUrl=defaultSuccessRedirectUrl;
        //该Map存放openId -> Obj
        this.openIdMap=new Map();
    }

    getUserInfoByToken(token){
        let openid= this.getOpenIdByToken(token);
        let userInfo=this.getUserInfoByOpenId(openid);
        return userInfo;
    }

    getUserInfoByOpenId(openid){
       let r= this.openIdMap.get("openid");
       return r;
    }

    /**
     * token与openId可以相互转换
     * @param openid
     */
    getTokenByOpenId(openid){
        return openid;
    }
    getOpenIdByToken(token){
        return token;
    }

    /**
     * 会员加到数据库
     * @param userInfoResult
     * @returns {Promise<void>}
     */
    async addMember2Db(userInfoResult){
        if(!userInfoResult.openid){
            return;
        }
        let memberList=await this.api.listAll({openid:userInfoResult.openid});
        if(memberList.length==0){
            this.api.add(userInfoResult);
        }
    }

    /**
     * 查询会员
     * @param openid
     * @returns {Promise<null|*>}
     */
   async getMemberFromDb(openid){
        let memberList=await this.api.listAll({openid:openid});
        if(memberList.length==0){
            return null;
        }
        return memberList[0];
    }

    install(app,args){
        //传入一个api插件用于存储数据
        this.api=args;
        //token验证
        app.get("/tokenVerify",(req,res)=>{
            res.send(req.params.echostr)
        })
        //测试openIdMap
        app.get("/openIdMap",(req,res)=>{
            res.send(this.openIdMap.keys())
        })

        app.get("/open/session",(req,res)=>{
            res.send(M.result(M.sessions))
        })
        if(1)
        app.use(["^/member"],async (req,res)=>{
            //带token说明已认证过
            if(req.session||req.headers["token"]){
                return;
            }
            let originalUrl=req.url;
            let state=this.proxy_redirect_uri +"?originalUrl="+originalUrl;
            //小程序没有登陆过,将小程序重定向到授权页
            let authLoginUrl=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${this.redirect_uri}&response_type=code&scope=snsapi_userinfo&state=${state}&connect_redirect=1#wechat_redirect`
            res.redirect(authLoginUrl);
        });
        app.get("/member/index",async (req,res)=>{
            //带token说明已认证过
             res.render("/index.html")
        });



        app.get("/member/list",(req,res)=>{
            res.send(M.result("okkkk"));
        })


        app.get("/open/member/login",async (req,res)=>{
            let openid=req.params.openid;
            let r=await this.getMemberFromDb(openid);
            if(r==null){
                res.send(M.failResult("登陆失败"))
            }else {
                req.session=r;
                res.send(M.successResult("登陆成功"))
            }
        });

        //这个接口要公网可访问,授权完,微信服务器重定向到这里,这里根据state并带上code再次重定向到本地/wx/wxcallback/local
        app.get(`/wx/getCode`,async (req,res)=>{
            let {state,code}=req.params;
            if (state.indexOf('?') === -1) {
                state = state + '?code=' + code;
            } else {
                state = state + '&code=' + code;
            }
            //state可能是开发环境电脑
            res.redirect(state);
        })



        app.get(`/wx/wxcallback/local`,async (req,res)=>{
            console.log("本机=======>",req.url)
            let {originalUrl,code}=req.params;
            //code 换 accessToken,code 只能用一次
            let getTokenUrl=`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appid}&secret=${this.appsecret}&code=${code}&grant_type=authorization_code`
            let accessTokenResult=await M.get(getTokenUrl)
            console.log("=====>accessTokenResult",accessTokenResult)
            //accessToken 换 userInfo
            let userInfoUrl=`https://api.weixin.qq.com/sns/userinfo?access_token=${accessTokenResult.access_token}&openid=${accessTokenResult.openid}&lang=zh_CN`
            let userInfoResult=await M.get(userInfoUrl)
            console.log("=====>userInfoResult",userInfoResult);
            this.addMember2Db(userInfoResult);
           // req.session=userInfoResult;
            res.redirect(`/login.html?openid=${accessTokenResult.openid}&originalUrl=${originalUrl}`);
        })


        /**
         * 这个用于js端调用 wexinApi,服务端域名与公众平台无关
         * <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
         */
        app.get(`${this.wxConfigServerUrl}`,async (req,res)=>{
            var params = req.params;
            var page = params.page||"http://localhost:8090/";
            console.log(params,"AAAAAAAAA")
            var timestamp = params.timestamp|| Date.now();
            var getToken="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+this.appid+"&secret="+this.appsecret;
            let r1= await  M.get(getToken);
            var access_token = r1.access_token;
            var getticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
            let r2= await  M.get(getticket);
            var ticket = r2.ticket;
            var string = 'jsapi_ticket=' + ticket + '&noncestr=Wm3WZYTPz0wzccnW&timestamp=' + timestamp + '&url=' + page;
            var sha1 = require('sha1');
            var signature = sha1(string);
            res.send(M.successResult({
                signature: signature,
                appId: this.appid,
                nonceStr: "Wm3WZYTPz0wzccnW"
            }))
        });

    }

}

module.exports = WxOfficialServerPlugin;

